#ifndef TRAJECTORY_H
#define TRAJECTORY_H

#include "vector3.h"

template <typename T>
class TrajectoryCalculator
{
public:
    enum eBehaviour
    {
        STRAIGHT,
        PARABOLIC_UP,
        PARABOLIC_DOWN
    };
    TrajectoryCalculator() {}
    virtual ~TrajectoryCalculator() {}
    virtual Vector3<T> interpolate(const Vector3<T> & from, const Vector3<T>& to, const T & prct) = 0;
    virtual eBehaviour myBehaviour() = 0;
};

template <typename T>
class StraightLine: public virtual TrajectoryCalculator<T>
{
public:
    StraightLine():TrajectoryCalculator<T>() {}
    ~StraightLine() {}
    Vector3<T> interpolate(const Vector3<T> & from, const Vector3<T> & to, const T & prct);
    TrajectoryCalculator<double>::eBehaviour myBehaviour() { return TrajectoryCalculator<double>::STRAIGHT; }; // trick to make it compile!
};

#include "straightline.inl"

template <typename T>
class ParabolicUp: public virtual TrajectoryCalculator<T>
{
public:
    ParabolicUp():TrajectoryCalculator<T>() {}
    ~ParabolicUp() {}
    Vector3<T> interpolate(const Vector3<T> & from, const Vector3<T> & to, const T & prct);
    TrajectoryCalculator<double>::eBehaviour myBehaviour() { return TrajectoryCalculator<double>::PARABOLIC_UP; }; // trick to make it compile!
};

#include "parabolicup.inl"

template <typename T>
class ParabolicDown: public virtual TrajectoryCalculator<T>
{
public:
    ParabolicDown():TrajectoryCalculator<T>() {}
    ~ParabolicDown() {}
    Vector3<T> interpolate(const Vector3<T> & from, const Vector3<T> & to, const T & prct);
    TrajectoryCalculator<double>::eBehaviour myBehaviour() { return TrajectoryCalculator<double>::PARABOLIC_DOWN; }; // trick to make it compile!
};

#include "parabolicdown.inl"

#endif // TRAJECTORY_H
